
'use strict';

const createConfig = require('uni-config-center');
const uidConfig = createConfig({
	pluginId: 'uni-id'
});

const db = uniCloud.database();
const dbcmd = db.command;

const { 
	wxapi,
	utils: wxutils
} = require('use-api');

const utils = require('../utils');

module.exports = {
	h5url: uidConfig.config('h5-weixin.url'),
	appid: uidConfig.config('h5-weixin.oauth.weixin.appid'),
	token: uidConfig.config('h5-weixin.server.token'),
	encodingAESKey: uidConfig.config('h5-weixin.server.encodingAESKey'),
	
	// 验证签名是否一致
	validSign: function(req) {
		// 微信公众号接入验证 GET 请求
		const {
			signature,
			timestamp,
			nonce,
			echostr
		} = req;
		
		const token = this.token;
		const str = [token, timestamp, nonce].sort().join('');
		// 验证签名是否一致
		const result = signature === utils.sha1(str);
		console.log('sha1 str', str, result);
		
		return result ? echostr : '验证签名失败';
	},
	// 处理 post 消息
	postMessage: async function(req) {
		// 回复消息
		let res = '';
		try{
			// 微信消息结构体
			const wxmsgObj = this.parseMessage(req);
			console.log('wxmsg', wxmsgObj);
			
			if (wxmsgObj.data.MsgType == 'event') {
				// 处理事件消息
				res = await this.eventMessage(wxmsgObj);
			} else {
				// 处理普通消息
				res = await this.generalMessage(wxmsgObj);
			}
			
			if (!res && wxmsgObj.data.FromUserName && wxmsgObj.data.ToUserName) {
				// 默认回复消息
				res = await this.replyDefaultMessage(wxmsgObj);
			}
		}catch(e){}
		
		return res;
	},
	// 解析消息
	parseMessage: function(req) {
		// 请求消息体
		const { body } = req;
		
		// xml 转 json 对象
		const rawmsg = utils.xmlToJson(body);
		// 不存在加密消息
		if (!rawmsg.Encrypt) {
			return {
				data: rawmsg,
				encrypt: 0
			};
		}
		
		// 解密消息体
		const decryptObj = utils.wxmsgDecrypt(this.encodingAESKey, rawmsg.Encrypt);
		console.log('rawmsg', rawmsg, decryptObj);
		// xml 转 json 对象
		const wxmsg = utils.xmlToJson(decryptObj.msg);
		
		return {
			data: wxmsg,
			encrypt: 1,
			appid: decryptObj.appid
		}
	},
	// 普通消息
	generalMessage: async function(wxmsg) {
		switch (wxmsg.data.MsgType){
			case 'text':				// 文本消息
				// 处理自动回复
				
				break;
			case 'image':				// 图片消息
				break;
			case 'voice':				// 语音消息
				break;
			case 'video':				// 视频消息
				break;
			case 'shortvideo':			// 小视频消息
				break;
			case 'location':			// 地理位置消息
				break;
			case 'link':				// 链接消息
				break;
			default:
				break;
		}
	},
	// 事件消息
	eventMessage: async function(wxmsg) {
		let res = '';
		switch (wxmsg.data.Event){
			case 'subscribe':				// 关注公众号（订阅）
				// 首次关注奖励积分
				await subscribeRewardIntegral(wxmsg);
				
				// 扫描带参数二维码事件 1. 用户未关注时，进行关注后的事件推送
				if (wxmsg.EventKey.includes('qrscene_')) {
					res = await this.scanMessage(wxmsg, wxmsg.data.EventKey.replace('qrscene_', ''));
				}
				break;
			case 'unsubscribe':				// 取消关注公众号（取消订阅）
				
				break;
			case 'SCAN':					// 扫描带参数二维码事件
				// 扫描带参数二维码事件 2. 用户已关注时的事件推送 
				res = await this.scanMessage(wxmsg, wxmsg.data.EventKey);
				break;
			case 'LOCATION':				// 上报地理位置事件
				break;
			case 'CLICK':					// 自定义菜单事件，点击菜单拉取消息时的事件推送
				break;
			case 'VIEW':					// 点击菜单跳转链接时的事件推送
				break;
			case 'TEMPLATESENDJOBFINISH':	// 模板消息事件推送
				break;
			default:
				break;
		}
		
		if (!res) res = 'success';
		
		return res;
	},
	// 扫一扫 消息
	scanMessage: async function(wxmsg, key) {
		
		const keys = key.split('_');
		if (keys.includes('usemall') && keys.includes('bindmsg')) {
			try {
				const openid = wxmsg.data.FromUserName;
				// 判断当前用户是否已注册
				const userRes = await db.collection('uni-id-users').where({
					wx_openid: {
						'h5-weixin': openid
					}
				}).field({ 
					wx_openid: true
				}).get();
				const [user] = userRes.data;
				
				if (!(user && user._id)) {
					const url = this.h5url || 'https://usemall-h5-wx.use-cloud.com';
					await this.sendTextMessage(wxmsg, `<a href="${url}">点击并授权获取个人信息后，重新扫码绑定</a>`);
					
					return 'success';
				}
				
				// 1. 扫码绑定消息通知 - 管理后台
				const sceneIds = keys.slice(2).map(x => parseInt(x));
				
				const res = await db.collection('usemall-message-type').where({
					scene: db.command.in(sceneIds)
				}).update({
					uids: db.command.addToSet(openid)
				});
				
				return this.replyTextMessage(wxmsg, `已绑定${res.updated}条消息通知，务必留意消息通知，并确保公众号 -> 设置 -> 消息免打扰 -> 关闭`); 
			} catch(e) {
				return this.replyTextMessage(wxmsg, `扫描结果-${key}，${e.message}`);
			}
		}
		
		if (keys.includes('usekf')) {
			return this.replyTextMessage(wxmsg, `usekf-扫描结果-${keys.slice(1).join('_')}`);
		}
		
		return '';
	},
	// 回复消息
	replyMessage: function(wxmsg, type, data) {
		// json 对象转 xml 格式
		const resxml = utils.jsonToXml({
			FromUserName: wxmsg.data.ToUserName,
			ToUserName: wxmsg.data.FromUserName,
			CreateTime: parseInt(Date.now() / 1000),
			MsgType: type,
			...data
		});
		
		console.log('resxml', resxml);
		// 非加密模式，直接返回
		if (!wxmsg.encrypt) {
			return resxml;
		}
		
		// 加密消息体
		const encryptObj = utils.wxmsgEncrypt(this.appid, this.token, this.encodingAESKey, resxml);
		// 加密后的对象转 xml
		const encryptXml = utils.jsonToXml(encryptObj);
		console.log('encryptXml', encryptXml);
		
		return encryptXml;
	},
	// 回复文本消息
	replyTextMessage: function(wxmsg, content) {
		return this.replyMessage(wxmsg, 'text', {
			Content: content
		});
	},
	
	// 回复默认消息
	replyDefaultMessage: async function(wxmsg) {
		const url = 'https://usekf-h5.use-cloud.com';
		await this.sendTextMessage(wxmsg, `<a href="${url}">点击联系1对1客服咨询</a>`);
		
		return 'success';
	},
	
	// 发生客服消息
	sendMessage: async function(wxmsg, data, valid) {
		const token = await wxapi.get_token(valid);
		const url = `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${token}`;
		
		// 发送 post 请求
		const res = await wxutils.http.post(url, {
			"touser": wxmsg.data.FromUserName,
			...data
		});
		console.log(url, data, res);
		
		if (res.errcode == 40001) {
			// 令牌失效
			return await this.sendMessage(wxmsg, data, true);
		}
		
		return res;
	},
	// 发送文本消息
	sendTextMessage: async function(wxmsg, content) {
		return await this.sendMessage(wxmsg, {
			"msgtype": 'text',
			"text": {
				content
			}
		});
	},
	
	// 关注奖励积分
	subscribeRewardIntegral: async function(wxmsg) {
		
	}
}
